package net.wangds.auth.menu.ctrl;

import net.wangds.auth.menu.conv.Res2SysMenuConv;
import net.wangds.auth.menu.module.MenuTypeEnum;
import net.wangds.auth.menu.module.SysMenu;
import net.wangds.auth.resource.comp.GeneralMenuComp;
import net.wangds.auth.resource.entity.GeneralResourceEntity;
import net.wangds.config.comp.SysConfComp;
import net.wangds.config.module.Config;
import net.wangds.data.Tree;
import net.wangds.jpa.Sorts;
import net.wangds.jpa.comp.AbstractRemovedComp;
import net.wangds.jpa.ctrl.AbstractJpaCompCtrl;
import net.wangds.web.entrypoint.BaseMultipleResp;
import net.wangds.web.entrypoint.PagingForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/menu")
@SuppressWarnings("unused")
public class MenuCtrl extends AbstractJpaCompCtrl<GeneralResourceEntity> {

    public static final String CONFIG_MENU_LABLE_CATA = "menu_label";


    @Autowired
    @SuppressWarnings("unused")
    private GeneralMenuComp mmCmpMenu;

    @Autowired
    @SuppressWarnings("unused")
    private SysConfComp mmCmpConf;

    private final Res2SysMenuConv mmConvRes2Sys = new Res2SysMenuConv();

    @Override
    protected AbstractRemovedComp<GeneralResourceEntity> fetchJpaComp() {
        return mmCmpMenu;
    }

    @Override
    protected BaseMultipleResp<GeneralResourceEntity> listWithKeywords(PagingForm page) {
        return mmConvPage2Resp.convert(mmCmpMenu.findByKeywords(page.getKeywords(), mmConvPf2Pr.convert(page)));
    }

    @RequestMapping(value="/{sys}", method = RequestMethod.POST)
    public BaseMultipleResp<SysMenu> fetchSystemMenus(
           @PathVariable("sys") String sys
    ){
        //LogHelper.dev("params sys:"+sys);
        List<GeneralResourceEntity> menus = mmCmpMenu.findMenus(sys);
        //Collections.reverse(menus);
        List<SysMenu> r = menus.stream().map(mmConvRes2Sys::convert
        ).collect(Collectors.toList());
        return BaseMultipleResp.list(buildMenuTrees(r));
    }

    @RequestMapping(value="/tree/allTree", method = RequestMethod.POST)
    public BaseMultipleResp<SysMenu> fetchAllTree(
    ){
        List<GeneralResourceEntity> menus = mmCmpMenu.findAll(Sorts.createTm_asc);
        //Collections.reverse(menus);
        List<SysMenu> r = menus.stream().map(mmConvRes2Sys::convert
        ).collect(Collectors.toList());
        return BaseMultipleResp.list(buildMenuTrees(r));
    }


    private List<SysMenu> buildMenuTrees(List<SysMenu> menus) {

        Map<String, SysMenu> map = new HashMap<>();

        menus.forEach(c->map.put(c.getId(),c));

        List<SysMenu> list = new ArrayList<>();

        menus.forEach(c->{
            String pid = c.getParentId();
            SysMenu m = map.get(pid);
            if(m==null){
                m = buildSysModuleMenu(pid);
                list.add(m);
                map.put(pid, m);
            }
        });

        list.addAll(menus);

        return Tree.trees(list);
    }

    private SysMenu buildSysModuleMenu(String id) {
        SysMenu res = new SysMenu();

        res.setId(id);
        res.setMenuType(MenuTypeEnum.CONTAINER);
        res.setMenuLabel(mmCmpConf.findByCataAndItem(CONFIG_MENU_LABLE_CATA, id)
                .map(Config::getText).orElse(id));

        return res;
    }

}
